package com.example.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.entity.CodeAssignmentRules;
import com.example.demo.entity.CodeHistory;
import com.example.demo.entity.CodingRules;
import com.example.demo.entity.RulesInfo;
import com.example.demo.mapper.CodeAssignmentRulesMapper;
import com.example.demo.mapper.CodingRulesMapper;
import com.example.demo.service.CodeAssignmentRulesService;
import com.example.demo.service.CodeHistoryService;
import com.example.demo.mapper.CodeHistoryMapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.WeekFields;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Random;

/**
* @author 18364
* @description 针对表【code_history】的数据库操作Service实现
* @createDate 2024-10-15 13:16:52
*/
@Service
public class CodeHistoryServiceImpl extends ServiceImpl<CodeHistoryMapper, CodeHistory>
    implements CodeHistoryService{
    @Autowired
    CodeAssignmentRulesMapper codeAssignmentRulesMapper;
    @Autowired
    CodingRulesMapper codingRulesMapper;
    @Autowired
    CodeHistoryMapper codeHistoryMapper;
    @Autowired
    CodeAssignmentRulesService codeAssignmentRulesService;

    @Override
    public List<CodeHistory> select(String userId,String appId, String trainingId) {
        QueryWrapper<CodeHistory> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("userId",userId);
        queryWrapper.eq("trainingId",trainingId);
        queryWrapper.eq("appId",appId);
        queryWrapper.orderByDesc("id");
        return codeHistoryMapper.selectList(queryWrapper);
    }

    @Override
    public CodeHistory selectByCodeInfo(String codeInfo) {
        QueryWrapper<CodeHistory> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("codeInfo",codeInfo);
        queryWrapper.orderByDesc("id");
        return codeHistoryMapper.selectOne(queryWrapper);
    }

    @Override
    public Integer delete(String appId, String trainingId, String userId) {
        QueryWrapper<CodeHistory> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("appId",appId);
        queryWrapper.eq("trainingId",trainingId);
        queryWrapper.eq("userId",userId);
        queryWrapper.orderByDesc("id");
        return codeHistoryMapper.delete(queryWrapper);
    }

    @Override
    public String makeCode(Integer codeId) {
        CodingRules codingRules=codingRulesMapper.selectById(codeId);
        if(codingRules==null){
            return null;
        }
        String str="";
        String batchNumber=getBatchNumber(codingRules);
        if(batchNumber!=null){
            str=str+batchNumber+",";
        }
        String serialNumber=getSerialNumber(codingRules);
        if(serialNumber!=null){
            str=str+serialNumber+",";
        }

        String randomNumber=getrandomNumber(codingRules);
        if(randomNumber!=null){
            str=str+randomNumber;
        }
        if(codingRules.getIsolate().equals("0")){
            str=str.replace(',', '.');
            str=removeTrailingDot(str);
        }else{
            str=str.replace(",", "");
        }
        return str;
    }

    @Override
    public Integer deleteByInfo(String appId, String trainingId, String userId, Integer type) {
        QueryWrapper<CodeHistory> queryWrapper=new QueryWrapper<>();
        if(appId!=null){
            queryWrapper.eq("appId",appId);
        }
        queryWrapper.eq("trainingId",trainingId);
        queryWrapper.eq("userId",userId);
        queryWrapper.eq("ruleType",type);
        return codeHistoryMapper.delete(queryWrapper);
    }

    @Override
    public List<CodeHistory> selectByProId(Integer proId) {
        QueryWrapper<CodeHistory> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("productInfoId",proId);
        queryWrapper.orderByDesc("id");
        return codeHistoryMapper.selectList(queryWrapper);
    }
    @Override
    public String make ( String userId, String appId, String trainingId,Integer ruleId,Integer productInfoId,String Code)  {

        CodeAssignmentRules codeAssignmentRules=codeAssignmentRulesService.selectById(ruleId);
        String lastCode=makeCode((Integer) codeAssignmentRules.getCodingid());
        if(lastCode==null){
            return null;
        }

        CodeHistory codeHistory=new CodeHistory();
        codeHistory.setCodeinfo(Code+"/"+lastCode);
        codeHistory.setRulesid(ruleId);
        codeHistory.setTrainingid(trainingId);
        codeHistory.setUserid(userId);
        codeHistory.setAppid(appId);
        codeHistory.setRuletype(0);
        codeHistory.setProductinfoid(productInfoId);
        save(codeHistory);
        return Code+"/"+lastCode;
    }

    public String getBatchNumber(CodingRules codingRules){
        if(!codingRules.getBatchnum().equals("")){
            String[] data=codingRules.getBatchnum().split(",");
            String str="";
            if(data[0].equals("0")){
                // 获取当前日期
                LocalDate currentDate = LocalDate.now();
                // 定义日期格式化为 YYYYMMDD
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
                // 格式化当前日期为字符串
                String formattedDate = currentDate.format(formatter);
                str=formattedDate;
            }else if(data[0].equals("1")){
                // 获取当前日期
                LocalDate currentDate = LocalDate.now();
                // 定义周字段，使用 ISO-8601 标准（周一为一周的第一天）
                WeekFields weekFields = WeekFields.of(Locale.getDefault());
                // 获取当前日期所在的周数和年份
                int weekOfYear = currentDate.get(weekFields.weekOfYear());
                int year = currentDate.getYear();
                // 格式化周数和年份为字符串
                String formattedWeek = String.format("%d%02d", year, weekOfYear);
                str=formattedWeek;
            }else{
                // 获取当前日期
                LocalDate currentDate = LocalDate.now();
                // 定义日期格式化为 YYYYMMDD
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMM");
                // 格式化当前日期为字符串
                String formattedMonth = currentDate.format(formatter);
                str=formattedMonth;
            }
            str=str+getSequenceCode(Integer.parseInt(data[1]));
            return str;
        }
        return null;
    }
    public String getSerialNumber(CodingRules codingRules){
        if(!codingRules.getSerialnum().equals("")){
            String[] data=codingRules.getSerialnum().split(",");
            String str="";
            if(!data[0].equals("")){
                List<String> characterList = new ArrayList<>();
                for (int i = 0; i < data[0].length(); i++) {
                    String a=getAlphabetFromC(data[0].charAt(i));
                    char randomCharacter = getRandomCharacterFrom(a);
                    str=str+randomCharacter;
                }

            }
            if(!data[2].equals("")){
                str=str+getSequenceCodeMin(Integer.parseInt(data[3]),Integer.parseInt(data[2]));
            }
            return str;
        }
        return null;
    }
    public String getrandomNumber(CodingRules codingRules){
        if(!codingRules.getRandomnum().equals("")){
            String[] data=codingRules.getRandomnum().split(",");
            String str="";
            if(!data[0].equals("")){
                String res=generateRandomUpperCaseString(Integer.parseInt(data[0]));
                str=str+res;
            }
            if(!data[1].equals("")){
                String res=getSequenceCode(Integer.parseInt(data[1]));
                str=str+res;
            }
            return str;
        }
        return null;
    }
    public String getSequenceCode(Integer n){
        int max = (int) Math.pow(10, n) - 1; // n位数的最大值，例如4位数最大为9999
        int min = 1; // n位数的最小值，这里我们排除0因为题目要求大于0
        Random random = new Random();

        // 生成一个n位数以内的随机数（大于0且小于max）
        int randomNumber = random.nextInt(max - min + 1) + min;

        // 格式化数字，确保前面有n-length(number)个零
        String formattedNumber = String.format("%0" + n + "d", randomNumber);
        return formattedNumber;
    }
    public String getSequenceCodeMin(Integer n,int m){
        int max = (int) Math.pow(10, n) - 1; // n位数的最大值，例如4位数最大为9999
        int min = m; // n位数的最小值，这里我们排除0因为题目要求大于0
        Random random = new Random();

        // 生成一个n位数以内的随机数（大于0且小于max）
        int randomNumber = random.nextInt(max - min + 1) + min;

        // 格式化数字，确保前面有n-length(number)个零
        String formattedNumber = String.format("%0" + n + "d", randomNumber);
        return formattedNumber;
    }
    public static String generateRandomUpperCaseString(int n) {
        if (n <= 0) {
            throw new IllegalArgumentException("位数n必须大于0");
        }

        StringBuilder sb = new StringBuilder(n);
        Random random = new Random();
        String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

        for (int i = 0; i < n; i++) {
            int index = random.nextInt(characters.length());
            sb.append(characters.charAt(index));
        }

        return sb.toString();
    }
    public static String getAlphabetFromC(char c) {
        StringBuilder sb = new StringBuilder();
        for (char ch = c; ch <= 'Z'; ch++) {
            sb.append(ch);
        }
        return sb.toString();
    }
    public static char getRandomCharacterFrom(String str) {
        Random random = new Random();
        int index = random.nextInt(str.length());
        return str.charAt(index);
    }
    public static String removeTrailingDot(String str) {
        // 检查字符串是否为空或长度为0，避免调用charAt时出现异常
        if (str == null || str.length() == 0) {
            return str; // 或者可以抛出一个异常，取决于你的需求
        }

        // 检查字符串的最后一个字符是否是点
        if (str.charAt(str.length() - 1) == '.') {
            // 返回一个新的字符串，不包含最后一个字符（即点）
            return str.substring(0, str.length() - 1);
        }

        // 如果最后一个字符不是点，就返回原始字符串
        return str;
    }
}




